﻿using System;
using System.Collections.Generic;
using System.Diagnostics;

using SchemaExplorer;

namespace CodeSmith.SchemaHelper
{
    public class EntityManager
    {
        #region Constructor(s)

        public EntityManager(DatabaseSchema database) : this(database.Tables) {}
        public EntityManager(TableSchemaCollection tables)
        {           
            ExcludedTables = new List<TableSchema>();
            Entities = new List<Entity>();

            if (tables != null && tables.Count > 0 && tables[0].Database != null)
            {
                Database = tables[0].Database;
                if (!Database.DeepLoad)
                {
                    Database.DeepLoad = true;
                    Database.Refresh();
                }

                int count = tables.Count;
                TableSchema table;
                string tableName;
                for (int i = 0; i < count; i++)
                {
                    /// Jack Modified at 2012-3-8
                    /// for Oracle EditableChild Lost ForeignKeys
                    /// TODO: this solution is temp,replace TableSchema with DatabaseSchema
                    tableName = tables[i].Name;
                    if (!tableCache.ContainsKey(tableName))
                    {                       
                        InsertTable(Database.Tables[tableName]);
                    }
                    table = tableCache[tableName];
                    tables[i] = table;
                //foreach ( TableSchema table in tables )
                //{                    
                    bool includeManyToMany = table.IsManyToMany() && !Configuration.Instance.IncludeManyToManyEntity;
                    if (Configuration.Instance.ExcludeRegexIsMatch(table.FullName) || includeManyToMany)
                        ExcludedTables.Add( table );
                    else if (!table.HasPrimaryKey)
                        Trace.WriteLine(string.Format("Skipping table: '{0}', no Primary Key was found!", table.Name));
                    else
                    {
                        Entities.Add(new Entity(table));
                    }
                }
            }
        }

        #endregion

        #region Public Read-Only Properties

        public List<Entity> Entities { get; private set; }
        public List<TableSchema> ExcludedTables { get; private set; }
        public DatabaseSchema Database { get; private set; }

        

        #endregion

        public static TableSchema GetTableSchema(string tableName)
        {
            return tableCache[tableName];
        }

        

        public static void InsertTable(TableSchema ts)
        {
            if (ts.Database.Provider.Name == "OracleSchemaProvider")
            {
                if (ts.PrimaryKey.MemberColumns[0].ExtendedProperties.Contains("CS_IsSequence"))
                {
                    ts.PrimaryKey.MemberColumns[0].ExtendedProperties["CS_IsSequence"].Value = true;
                }
                else
                {
                    ts.PrimaryKey.MemberColumns[0].ExtendedProperties.Add(new ExtendedProperty("CS_IsSequence", true, System.Data.DbType.Boolean));
                }
            }            
            tableCache.Add(ts.Name, ts);
        }

        public static TableSchema EnsureTable(TableSchema ts)
        {
            TableSchema table = GetTableSchema(ts.Name);
            if (table != null)
            {
                ts = table;
                return table;
            }

            ts = table = ts.Database.Tables[ts.Name];

            if (ts.Database.Provider.Name == "OracleSchemaProvider")
            {
                if (ts.PrimaryKey.MemberColumns[0].ExtendedProperties.Contains("CS_IsSequence"))
                {
                    ts.PrimaryKey.MemberColumns[0].ExtendedProperties["CS_IsSequence"].Value = true;
                }
                else
                {
                    ts.PrimaryKey.MemberColumns[0].ExtendedProperties.Add(new ExtendedProperty("CS_IsSequence", true, System.Data.DbType.Boolean));
                }
            }
            tableCache.Add(ts.Name, ts);

            return table;
        }
        static Dictionary<string, TableSchema> tableCache = new Dictionary<string,TableSchema>();
        
    }
}